package io.sundial.job;

import com.google.common.base.Preconditions;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * 作业执行
 *
 * @author Payne 646742615@qq.com
 * 2018/12/20 13:46
 */
public class JobExecution extends FutureTask<JobResult> {
    private final JobCommand jobCommand;
    private final JobCancellation jobCancellation;
    private volatile JobStatus jobStatus;
    private volatile JobResult jobResult;
    private volatile JobException jobException;

    public JobExecution(Callable<JobResult> callable, JobCommand jobCommand, JobCancellation jobCancellation) {
        super(callable);
        Preconditions.checkNotNull(jobCommand, "jobCommand must not be null");
        this.jobCommand = jobCommand;
        this.jobCancellation = jobCancellation;
    }

    @Override
    public void run() {
        try {
            super.run();
            jobStatus = JobStatus.COMPLETED;
            jobResult = get();
        } catch (Exception e) {
            jobStatus = JobStatus.FAILED;
            jobException = new JobException(e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        boolean canceled = super.cancel(mayInterruptIfRunning);
        if (canceled) {
            jobStatus = JobStatus.CANCELED;
            if (jobCancellation != null) {
                jobCancellation.onCanceled(jobCommand);
            }
        }
        return canceled;
    }

    public JobCommand getJobCommand() {
        return jobCommand;
    }

    public JobCancellation getJobCancellation() {
        return jobCancellation;
    }

    public JobStatus getJobStatus() {
        return jobStatus;
    }

    public void setJobStatus(JobStatus jobStatus) {
        this.jobStatus = jobStatus;
    }

    public JobResult getJobResult() {
        return jobResult;
    }

    public void setJobResult(JobResult jobResult) {
        this.jobResult = jobResult;
    }

    public JobException getJobException() {
        return jobException;
    }

    public void setJobException(JobException jobException) {
        this.jobException = jobException;
    }
}
